package com.kim.authorization.server.config.extend;

import com.kim.authorization.server.config.util.AuthProperties;
import com.kim.authorization.server.service.UserAccountService;
import com.kim.common.utilcom.utils.BpwdEncoderUtil;
import com.kim.oauth.common.constants.Oauth2ExceptionEnum;
import com.kim.oauth.common.model.UserAccount;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * 用户名密码授权类型鉴权
 */
@Component
@Primary
@Slf4j
public class UsernamePasswordAuthenticator extends AbstractPrepareIntegrationAuthenticator {

    /**
     * 用户名密码授权类型
     */
    private final static String AUTH_TYPE = "password";

    /**
     * 用户账户Service
     */
    @Resource
    private UserAccountService userAccountService;

    /**
     * 根据用户名密码方式进行认证
     *
     * @param entity 集成认证实体
     * @return org.surge.oauth2common.model.UserAccount
     */
    @Override
    public UserAccount authenticate(IntegrationAuthenticationEntity entity) {

        // 获取用户名密码
        String username = entity.getAuthParameter(AuthProperties.USERNAME_PARAMETER_NAME);
        String password = entity.getAuthParameter(AuthProperties.PASSWORD_PARAMETER_NAME);

        // 用户名或密码为空
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
            throw new OAuth2Exception(Oauth2ExceptionEnum.USERNAME_OR_PASSWORD_NULL.getMsg());
        }
        // 根据用户名或手机号查询用户账户
        UserAccount userAccount = userAccountService.selectByUserName(username);
        if (null == userAccount) {
            throw new OAuth2Exception(Oauth2ExceptionEnum.USER_NOT_FOUND.getMsg());
        }
        // 验证密码正确性
        if (!BpwdEncoderUtil.matches(password, userAccount.getPassword())) {
            throw new OAuth2Exception(Oauth2ExceptionEnum.PASSWORD_ERR.getMsg());
        }
        // 验证用户可用性
        userAccountService.validateUser(userAccount);

        // 组合用户账户对象与角色权限
        return userAccountService.composeUserAccountAndAuthority(userAccount);
    }

    /**
     * 认证类型为空时为用户名密码方式
     * {@inheritDoc}
     */
    @Override
    public boolean support(IntegrationAuthenticationEntity entity) {
        // 认证类型
        String authType = entity.getAuthType();
        return StringUtils.isEmpty(authType) || authType.equals(AUTH_TYPE);
    }

}
